<?php

namespace App\Http\Controllers;

use App\Http\Service\FinishBidding;
use App\Models\Product;
use App\Models\ProductBid;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

class ProductController extends Controller
{

    public function index(FinishBidding $finishBidding)
    {
        $finishBidding->handle();
        $products = Product::query()->where('on_sale', true)->paginate(10);
        return view('product.index', compact('products'));
    }

    public function show(Product $product, FinishBidding $finishBidding)
    {
        $finishBidding->handle();    // 每个用户访问的时候都会触发本函数

        $product = $product->load(['biddingList' => function ($query) {
            $query->orderBy('created_at', 'desc')->take(4);  // 默认只获取4条数据
        }]);

        // 计算参与竞拍的人数
        $product->participate_count = $product->biddingList->pluck('user_id')->unique()->count() ?? 0;
        $product->lastBiddingId = $product->biddingList->first()->id ?? 0;
        $product->bid_price = $product->biddingList->isEmpty() ? $product->price : $product->biddingList->max('price');  //商品当前的拍卖价格
        session(['product.lastBiddingId' => $product->lastBiddingId]);
        $product->biddingList = $product->biddingList->reverse();  // 反转数据

        return view('product.show', compact('product'));
    }

    // 竞价
    public function bidding(Product $product, Request $request, FinishBidding $finishBidding)
    {
        $finishBidding->handle();

        // 还未上架
        if (!$product->on_sale) {
            return $this->return_error('商品未上架');
        }

        // 还没有开始竞拍
        if ($product->type == Product::TYPE_PENDING) {
            return $this->return_error('竞拍未开始');
        }

        // 竞拍已结束
        if ($product->type != Product::TYPE_BIDDING) {
            return $this->return_error('竞拍已结束');
        }

        // 事务, 使用悲观锁
        DB::transaction(function () use ($product, $request) {
            $money = $request->input('money');
            // 获取上一个竞价列表, 增加悲观锁, 防止本条数据被读取, 直到事务结束
            $preBiddingProduct = $product->biddingList()->orderBy('created_at', 'desc')->lockForUpdate()->first();

            $nowPrice = $preBiddingProduct ? $preBiddingProduct->now_price + $money : $product->price + $money;

            $people_count = $product->biddingList->pluck('user_id')->unique()->count();
            $product->people_count = $people_count;
            $product->save();

            $request->user()->biddingProduct()->attach($product->id, [
                'money' => $money,
                'now_price' => $nowPrice
            ]);
        });



        return $this->return_message('加价成功');
    }

    // 轮询数据
    public function getBiddingListByBiddingId(Product $product, Request $request, FinishBidding $finishBidding)
    {
        $this->autoBid($finishBidding);

        $biddingId = $request->input('bidding_id');
        $biddingList = $product->biddingList()->with('user')
            ->where('id', '>', $biddingId)
            ->orderBy('created_at', 'asc')
            ->get();

        $oldLastBiddingId = session("product.lastBiddingId");
        if (!$biddingList->last()) {
            return $this->return_success([]);
        }

        $nowBiddingListId = $biddingList->last()->id;
        session(["product.lastBiddingId" => $nowBiddingListId]);

        if ($nowBiddingListId == $oldLastBiddingId) {
            return $this->return_success([]);
        }

        return $this->return_success($biddingList);
    }

    private function autoBid($finishBidding) {
        if (Arr::random([1, 2, 3, 4, 5]) == 1) {
            // 有1 / 5的几率触发自动加价
            $finishBidding->autoBid();
        }
    }

    // 此接口用于结束物品拍卖
    public function finishBidding(FinishBidding $finishBidding)
    {
        $finishBidding->handle();
    }


    public function return_success($data)
    {
        return response([
            'data' => $data,
            'status' => 'success',
            'code' => 200
        ], 200);
    }

    public function return_message($message)
    {
        return response([
            'message' => $message,
            'status' => 'success',
            'code' => 200
        ], 200);
    }

    public function return_error($message)
    {
        return response([
            'message' => $message,
            'status' => 'error',
            'code' => 400
        ], 400);
    }
}
